/**
 * @class   wosh::services::DiscoveryUdpBundle
 * @brief   Implements \ref wosh::interfaces::services::Discovery "Host Discovery service" on top of UDP.
 *
 * Discovery service enables the (reciprocal) discovery of WOSH hosts
 * sending and receiving information as UDP datagrams.
 * The service interacts with wosh::NetworkManager which holds the
 * updated list of all known WOSH hosts of the wosh-network.
 *
 * The DiscoveryUdpBundle service is (build and) installed on all WOSH Applications and represents
 * the most common Host-Discovery service.
 *
 * A sample configuration is available: <a href="../../etc/wosh/bundles-available/001_DiscoveryUdp.conf">001_DiscoveryUdp.conf</a>
 *
 *
 * The service runs an UDP server on local-host (you may bind it to ANY interface on most platforms)
 * listening for incomin packets (sent by remote hosts); periodically it broadcast discovery-messages
 * to one or more hosts (address/port), frequency is configurable.
 *
 * Most important Properties are:
 *  - \c BindAddressPort - set to local address:port (default '0.0.0.0:8787' binds to any interface)
 *  - \c BroadcastAddressPort - set to remote address:port, separated by ';' (such as '192.168.0.255:8787;192.168.1.255:8787' )
 *  - \c NotifyFrequency - set the interval of discovery, in seconds (default 60 = 1 minute)
 *
 * These fields and the important role of Discovery service is deeply related to \ref page_core_network "WOSH Networking".
 *
 * @par Network configuration notes
 *  The internal \ref wosh::network::SocketUdp "UDP socket" provides two useful functionalities:
 *   - It's capable of binding to ANY network-interface (on almost all platforms), in most case you may just
 *     leave the default binding address, DiscoveryUdp will listen on all interfaces (network-card) at port 8787
 *   - Allow broadcast packets (again it partially depends on the platform, but last subnet x.y.z.255 is
 *     always supported). In short, set the broadcast network-mask(s) of your host(s).
 *
 * Suppose you have a LAN with two or more hosts, their IP looks like X.Y.Z.<NODE-id> (192.168.0.1, 192.168.0.56 and so on),
 * then settings are the same for all hosts: Bind to '0.0.0.0:8787' and Broadcast to 'X.Y.Z.255:8787'.
 * A more complex case is the following: one of these hosts is a sort of gateway and is connected to another
 * LAN (as the wireless-network), let's say A.B.C (192.168.1.x), then just add 'A.B.C.255:8787' to the Broadcast
 * list (of all hosts), so it looks like '192.168.0.255:8787;192.168.1.255:8787'.
 *
 * \note
 *  The DiscoveryUdp service is not intented to discover WOSH hosts over the Internet (because of UDP routing
 *  and security-issues both), but only within a (local) trusted-network.
 *
 *
 * @par Packet format
 *  Discovery packet is represented by DiscoveryUdpMessage, which implements (de)serialization routines.
 *
 * Theorically almost all fields of WoshHost may be sent, actually only few of them are required by the WOSH networking-system.
 * Most important fields included in package are:
 *  - \c Kernel-Name - name of wosh::the WoshKernel
 *  - \c Bind-Address - of the remote DiscoveryUdp service
 *  - \c Notify-Frequenct - of the remote DiscoveryUdp service, used to estimate timeout
 *  - \c Supported-Protocols - the communication-protocols supported by the host (such as TCP:://192.168.0.1:9797)
 *  - \c Neighbours - neighbour hosts, used by NetworkManager to keep smart routing table
 *
 *
 * @par Outgoing message Flow
 *  DiscoveryUdpMessage is generated from local wosh::WoshHost, retrieved calling wosh::NetworkManager::getLocalWoshHost().
 *  Sending action is always asynchronous (performed by internal thread).
 *
 * \msc
DiscoveryUdp, NetworkManager, SocketUdp;
DiscoveryUdp=>NetworkManager [ label="retrieve local-host info", URL="\ref wosh::NetworkManager::getLocalWoshHost()" ];
DiscoveryUdp<-NetworkManager [ label="copy of wosh::WoshHost" ];
|||;
DiscoveryUdp=>DiscoveryUdp [ label="update outgoing discovery-packet from WoshHost", URL="\ref DiscoveryUdpImpl::updateMessageByHost()" ];
DiscoveryUdp=>DiscoveryUdp [ label="serialize the datagram", URL="\ref wosh::DiscoveryUdpMessage::saveTo()" ];
|||;
DiscoveryUdp=>SocketUdp [ label="send the datagram", URL="\ref wosh::network::SocketUdp::sendDatagram()" ];
 * \endmsc
 *
 *
 * @par Incoming message Flow
 *  Incoming datagrams are converted to wosh::WoshHost object and 
 *  forwarded to wosh::NetworkManager::updateWoshHost().
 * \msc
SocketUdp, DiscoveryUdp, NetworkManager;
SocketUdp<=DiscoveryUdp [ label="bind socket", URL="\ref wosh::network::SocketUdp::bindSocket()" ];
--- [ label=" Bundle Running "];
|||;
SocketUdp=>DiscoveryUdp [ label="incoming datagram", URL="\ref DiscoveryUdpImpl::udpIncomingDatagram()" ];
|||;
DiscoveryUdp=>DiscoveryUdp [ label="extract WoshHost info from discovery-packet", URL="\ref DiscoveryUdpImpl::updateHostByMessage()" ];
|||;
DiscoveryUdp=>NetworkManager [ label="forward updated host data", URL="\ref wosh::NetworkManager::updateWoshHost()" ];
|||;
--- [ label=" Bundle Stopping "];
SocketUdp<=DiscoveryUdp [ label="unbind socket", URL="\ref wosh::network::SocketUdp::unbindSocket()" ];
 * \endmsc
 *
 * A typical log-output emphatizing the system-results of an incoming Discovery packet is:
 * \verbatim
I^18:39:26   NetworkManager:updateWoshHost(wosh28, 1,0, -2) Updated Host
\endverbatim
 *
 *
 * DiscoveryUdp is a wrapper (bundle-adapter), real implementation is DiscoveryUdpImpl.
 *
 * @see     wosh::NetworkManager, wosh::WoshHost
 * @see     wosh::interfaces::services::Discovery, wosh::interfaces::services::DiscoveryUdp
 * @ingroup Services
 ****************************************************************************
 * @version 0.8.384 $Id: DiscoveryUdpBundle.h 2289 2010-04-09 09:14:03Z alex $
 * @date    Released Stable on 2010-02-21
 * @author  Alessandro Polo
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/

#ifndef __WOSH_Bundles_Services_DiscoveryUdp_H__
 #define __WOSH_Bundles_Services_DiscoveryUdp_H__

 #include <core/BundleGeneric.h>
 #include <interfaces/Service.h>
 #include <interfaces/services/DiscoveryUdp.h>

class DiscoveryUdpImpl;

namespace wosh {
 namespace services {

 #define _DiscoveryUdp_NAME							"Discovery"
 #define _DiscoveryUdp_VERSION						1.27

 #define _DiscoveryUdp_DEFAULT_NotifyFrequency		60
 
 #define _DiscoveryUdp_DEFAULT_BindAddressPort		"0.0.0.0:8787"
 #define _DiscoveryUdp_DEFAULT_BroadcastAddressPort	"192.168.0.255:8787"


class DiscoveryUdpBundle :	public wosh::BundleGeneric,
							public virtual wosh::interfaces::services::DiscoveryUdp
 {
	WOSH_BUNDLE(wosh::services::DiscoveryUdpBundle)
	WOSH_BUNDLE_INTERFACE("wosh::interfaces::services::DiscoveryUdp")
	WOSH_BUNDLE_SINGLETON(1,0)


	public:
		/**
		 * @brief   Empty constructor, init bundle and vars, Properties and Methods.
		 */
		DiscoveryUdpBundle();
		/**
		 * @brief   Empty destructor, may (synch) stop bundle and internal threads when still running
		 */
		virtual ~DiscoveryUdpBundle();


	public:
		WRESULT bundleStart();
		WRESULT bundleStop();

		bool updatingProperty( bool& do_update, const Variant& value_proposed, Property& property_current, const PropertiesProvider* source );


/** @name Discovery Interface
 * @{
 ******************************************************************************/
	public:
		WRESULT doAnnounceLocalHost();
//@}

	private:
		Response* mmDoDiscovery( const Request* request );

	protected:
		DiscoveryUdpImpl* discWorker;		///< real implementation based on wosh::BundleGenericWorker (worker thread)


}; // class def

 }; // namespace services
}; // namespace wosh

#endif //__WOSH_Bundles_Services_DiscoveryUdp_H__
